package com.gugee.ins.data.blogger.statistics.core;

import com.gugee.ins.common.dal.service.statistics.InsStBloggerRealFollowingDao;
import com.gugee.ins.common.dal.service.media.InsMediaDao;
import com.gugee.ins.common.dto.InsAdMediaStInfoDto;
import com.gugee.ins.common.model.mysql.blogger.InsBloggerMain;
import com.gugee.ins.common.model.mysql.statistics.InsStBloggerRealFollowing;
import com.gugee.ins.data.common.msg.InsBloggerMessage;
import com.xiguaji.boot.toolkit.ThreadPoolUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * 广告贴子统计
 */
@Service
public class StBloggerMediaAdService extends StBaseService{

    /**
     *
     */
    private static final String THREAD_POOL_NAME = "BloggerMediaAd-Thread";

    /**
     *
     */
    @Autowired
    private InsMediaDao insMediaDao;

    /**
     *
     */
    @Autowired
    private InsStBloggerRealFollowingDao insStBloggerRealFollowingDao;

    /**
     *
     */
    @Autowired
    @Qualifier("insBloggerMsgBaseInfoProducer")
    private KafkaTemplate<Long, InsBloggerMessage> insBloggerMsgBaseInfoProducer;

    /**
     *
     */
    @PostConstruct
    public void init() {
        forkJoinPool = ThreadPoolUtils.forkJoinPool(bloggerStatisticsAppConfig.getBloggerActiveFollowerDataThreadPoolSize(), THREAD_POOL_NAME);
        scheduleTemplate.attach(THREAD_POOL_NAME, forkJoinPool);
        workName = "BloggerMediaAd";
    }

    /**
     *
     * @param insBloggerMessage
     */
    @Override
    protected void statistics(InsBloggerMessage insBloggerMessage) {
        // 当前时间戳
        long start = System.currentTimeMillis() / 1000;
        // 时间区间
        long timeRang = start - bloggerStatisticsAppConfig.getLatestDays() * 24 * 3600;
        long timeRangWeek = start - 7 * 24 * 3600;

        // 查询数据库
        InsStBloggerRealFollowing insStBloggerRealFollowing = insStBloggerRealFollowingDao.findByUid(insBloggerMessage.getUid());
        // 判断是否最近更新过，更新过就不再更新
        if(checkUpdate(insStBloggerRealFollowing)){
            return;
        }
        InsBloggerMain insBloggerMain = insBloggerMainDao.findByUid(insBloggerMessage.getUid());

        // 获取帖子总数
        int total = insMediaDao.getMediaTotal(insBloggerMessage.getUid(),timeRang);
        if(insBloggerMain == null){
            return;
        }
        long now = System.currentTimeMillis() / 1000;
        // 广告帖子总数
        int adTotal = 0;
        // 广告帖子er
        double adER = 0.0;
        // 不存在就创建一个
        if(null == insStBloggerRealFollowing){
            insStBloggerRealFollowing = new InsStBloggerRealFollowing();
            insStBloggerRealFollowing.setUid(insBloggerMessage.getUid());
            insStBloggerRealFollowing.setCreateTime(now);
        }
        // 设置冗余字段
        insStBloggerRealFollowing.setFollowerCount(insBloggerMain.getFollowerCount());
        insStBloggerRealFollowing.setFollowerSize(insBloggerMain.getFollowerSize());
        insStBloggerRealFollowing.setCategoryName(insBloggerMain.getCategoryName());
        insStBloggerRealFollowing.setOverallCategoryName(insBloggerMain.getOverallCategoryName());
        if(total == 0){
            // 设置默认值
            setDefaultZero(insStBloggerRealFollowing);
        } else{
            // 获取广告图文、视频的平均参与率 和 帖子数
            List<InsAdMediaStInfoDto> insAdMediaStInfos = insMediaDao.getAdMediaInfoByUid(insBloggerMessage.getUid(),timeRang);
            if(insAdMediaStInfos != null && !insAdMediaStInfos.isEmpty()){
                // 计算广告帖子的平均参与率 和 帖子数
                for(InsAdMediaStInfoDto insAdMediaStInfoDto : insAdMediaStInfos){
                    if(insAdMediaStInfoDto != null){
                        adTotal += insAdMediaStInfoDto.getTotal();
                        adER += insAdMediaStInfoDto.getAdEr() * insAdMediaStInfoDto.getTotal();
                        if(insAdMediaStInfoDto.getIsVideo()){
                            insStBloggerRealFollowing.setAdVideoCount(insAdMediaStInfoDto.getTotal());
                            insStBloggerRealFollowing.setAdVideoEr(insAdMediaStInfoDto.getAdEr());
                            insStBloggerRealFollowing.setAdVideoEvc(insAdMediaStInfoDto.getVideoViewCount());
                            insStBloggerRealFollowing.setAdVideoRate((double)insAdMediaStInfoDto.getTotal() / total);
                            insStBloggerRealFollowing.setAdVideoEc(Math.round(insAdMediaStInfoDto.getAdEr() * insBloggerMain.getFollowerCount()));
                        }else{
                            insStBloggerRealFollowing.setAdImageCount(insAdMediaStInfoDto.getTotal());
                            insStBloggerRealFollowing.setAdImageEr(insAdMediaStInfoDto.getAdEr());
                            insStBloggerRealFollowing.setAdImageRate((double)insAdMediaStInfoDto.getTotal() / total);
                            insStBloggerRealFollowing.setAdImageEc(Math.round(insAdMediaStInfoDto.getAdEr() * insBloggerMain.getFollowerCount()));
                        }
                    }
                }
                adER = adTotal > 1 ? adER / adTotal : adER;
                insStBloggerRealFollowing.setAdCount(adTotal);
                insStBloggerRealFollowing.setBrandMediaRate((double)adTotal / total);
                insStBloggerRealFollowing.setBrandMediaEr(adER);
                insStBloggerRealFollowing.setAdEc(Math.round(adER * insBloggerMain.getFollowerCount()));
                insStBloggerRealFollowing.setLastAdStTime(now);
                insStBloggerRealFollowing.setAdTec(insStBloggerRealFollowing.getAdEc() * adTotal);

                // 统计周信息
                statisticsWeek(insBloggerMessage.getUid(),timeRangWeek,insBloggerMain.getFollowerCount(),insStBloggerRealFollowing);
            }else{
                setDefaultZero(insStBloggerRealFollowing);
            }
        }
        insStBloggerRealFollowing.setLastAdStTime(now);
        // 保存
        insStBloggerRealFollowingDao.saveOrUpdate(insStBloggerRealFollowing);
        // 同步到大播主表
        insBloggerMainDao.updateBrandMediaEr(insBloggerMessage.getUid(),adER);
        // 发送同步es消息
        sendMsg(insBloggerMessage);
    }

    /**
     * 设置默认0值
     * @param insStBloggerRealFollowing
     */
    public void setDefaultZero(InsStBloggerRealFollowing insStBloggerRealFollowing){
        insStBloggerRealFollowing.setAdVideoCount(0);
        insStBloggerRealFollowing.setAdVideoEr(0.0);
        insStBloggerRealFollowing.setAdVideoEvc(0L);
        insStBloggerRealFollowing.setAdVideoRate(0.0);
        insStBloggerRealFollowing.setAdVideoEc(0L);
        insStBloggerRealFollowing.setAdImageCount(0);
        insStBloggerRealFollowing.setAdImageEr(0.0);
        insStBloggerRealFollowing.setAdImageRate(0.0);
        insStBloggerRealFollowing.setAdImageEc(0L);
        insStBloggerRealFollowing.setAdCount(0);
        insStBloggerRealFollowing.setBrandMediaRate(0.0);
        insStBloggerRealFollowing.setBrandMediaEr(0.0);
        insStBloggerRealFollowing.setAdEc(0L);
        insStBloggerRealFollowing.setAdTec(0L);
        setDefaultZeroWeek(insStBloggerRealFollowing);
    }

    /**
     * 设置默认0值
     * @param insStBloggerRealFollowing
     */
    public void setDefaultZeroWeek(InsStBloggerRealFollowing insStBloggerRealFollowing){
        insStBloggerRealFollowing.setAdCountWeek(0);
        insStBloggerRealFollowing.setAdTecWeek(0L);
    }

    /**
     * 统计近一周的数据
     * @param uid
     * @param timeRang
     * @param followerCount
     * @param insStBloggerRealFollowing
     */
    public void statisticsWeek(long uid, long timeRang,long followerCount,InsStBloggerRealFollowing insStBloggerRealFollowing){
        InsAdMediaStInfoDto insAdMediaStInfoDto = insMediaDao.getAdMediaInfoForWeekByUid(uid,timeRang);
        if(insAdMediaStInfoDto != null){
            int total = insAdMediaStInfoDto.getTotal() != null ? insAdMediaStInfoDto.getTotal() : 0;
            double er = insAdMediaStInfoDto.getAdEr() != null ? insAdMediaStInfoDto.getAdEr() : 0.0;
            insStBloggerRealFollowing.setAdCountWeek(total);
            insStBloggerRealFollowing.setAdTecWeek(total * Math.round(er * followerCount));
        }else{
            setDefaultZeroWeek(insStBloggerRealFollowing);
        }
    }

    /**
     * 发送同步es数据
     * @param insBloggerMessage
     */
    public void sendMsg(InsBloggerMessage insBloggerMessage){
        insBloggerMessage.setRetryTimes(bloggerStatisticsAppConfig.getInsMBMediaAdToEsRetryTimes());
        insBloggerMessage.setRetryLimitTimes(bloggerStatisticsAppConfig.getInsMBMediaAdToEsRetryTimes());
        insBloggerMessage.setEventTime(System.currentTimeMillis());
        insBloggerMsgBaseInfoProducer.send(bloggerStatisticsAppConfig.getInsMBMediaAdToEsTopic(),insBloggerMessage);
    }

    /**
     * 判断是否最近更新过，更新过就不再更新
     * @param insStBloggerRealFollowing
     * @return
     */
    public boolean checkUpdate(InsStBloggerRealFollowing insStBloggerRealFollowing){
        long limitTime = System.currentTimeMillis() / 1000 - bloggerStatisticsAppConfig.getStAdMediaIntervalHours() * 3600;
        if(insStBloggerRealFollowing == null || insStBloggerRealFollowing.getLastAdStTime() < limitTime){
            return false;
        }
        return true;
    }
}
